﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using FireStarter.Base;
using FireStarterModeller.BO;
using FireStarterModeller.Logic;
using Habanero.Base;
using Habanero.BO;
using Habanero.BO.ClassDefinition;
using Habanero.BO.Loaders;
using Habanero.Faces.Base;
using Habanero.Faces.Win;

namespace FireStarterModeller.UI.ViewEditor
{
    public class UIViewsEditorControl :  UserControlWin, IUIViewsEditorControl
    {
        private readonly IFireStarterFormsController _formsController;
        private readonly IGroupBox _previewControlGroupBox;
        private readonly IPanel _panel;

        internal IControlFactory ControlFactory { get; private set; }

        public IUIXmlEditorControl XMLEditorControl { get; private set; }

        public IUIPreviewControl PreviewControl { get; private set; }

        public IUIViewSelectorControl SelectorControl { get; private set; }

        public IConverter<DMSolution, ClassDefCol> DMClassToClassDefConverter { get; private set; }

        public IButton PreviewGridButton { get; private set; }
        public IButton PreviewFormButton { get; private set; }
        public IButton ApplyChangesButton { get; private set; }
        public IButton UndoPreviewButton { get; private set; }
        private DMClass DMClass { get; set; }
        //internal IClassDef ClassDef { get; set; }

        public UIViewsEditorControl(IControlFactory controlFactory, IFireStarterFormsController formsController, IUIXmlEditorControl xmlEditorControl,
            IUIPreviewControl previewControl, IUIViewSelectorControl selectorControl, IConverter<DMSolution, ClassDefCol> converter)
        {
            _formsController = formsController;
            ControlFactory = controlFactory;
            XMLEditorControl = xmlEditorControl;
            PreviewControl = previewControl;
            SelectorControl = selectorControl;
            DMClassToClassDefConverter = converter;

            IButtonGroupControl buttonGroupControl = ControlFactory.CreateButtonGroupControl();
          
                  
            PreviewGridButton = buttonGroupControl.AddButton("Preview Grid", "Preview Grid", PreviewGridButton_OnClick);
            PreviewFormButton = buttonGroupControl.AddButton("Preview Form", "Preview Form", PreviewFormButton_OnClick);
            ApplyChangesButton = buttonGroupControl.AddButton("Apply Changes", ApplyChanges_Click);
            UndoPreviewButton = buttonGroupControl.AddButton("Undo Preview", UndoPreviewButton_OnClick);
            UndoPreviewButton.Enabled = false;
           // IPanel editorAndButtonsControl = _controlFactory.CreatePanel(_controlFactory);

            _previewControlGroupBox = ControlFactory.CreateGroupBox("Preview");
            if (xmlEditorControl is Control)
            {
                this.Controls.Clear();
                IGroupBox editorGroupBox = ControlFactory.CreateGroupBox("UI Definition Editor");
                BorderLayoutManager editorGroupBoxManager = ControlFactory.CreateBorderLayoutManager(editorGroupBox);
                editorGroupBoxManager.AddControl(selectorControl, BorderLayoutManager.Position.North);
                editorGroupBoxManager.AddControl(XMLEditorControl, BorderLayoutManager.Position.Centre);
                editorGroupBoxManager.AddControl(buttonGroupControl, BorderLayoutManager.Position.South);
                
                Padding padding = new Padding(10);
                ((GroupBoxWin) _previewControlGroupBox).Padding = padding;
                BorderLayoutManager previewControlGroupBoxManager =
                    ControlFactory.CreateBorderLayoutManager(_previewControlGroupBox);
                previewControlGroupBoxManager.AddControl(PreviewControl, BorderLayoutManager.Position.Centre);

                 _panel = ControlFactory.CreatePanel();
                ((PanelWin)_panel).Padding = new Padding(5);
                BorderLayoutManager panelManager = 
                    ControlFactory.CreateBorderLayoutManager(_panel);
                panelManager.AddControl(_previewControlGroupBox, BorderLayoutManager.Position.Centre);

                BorderLayoutManager manager = ControlFactory.CreateBorderLayoutManager(this);
                manager.AddControl(_panel, BorderLayoutManager.Position.South, true);
                manager.AddControl(editorGroupBox, BorderLayoutManager.Position.Centre);
            }

            SelectorControl.UIViewSelected += SelectorControl_OnUIViewSelected;
            UpdateState();
        }


        private void UndoPreviewButton_OnClick(object sender, EventArgs e)
        {
            try
            {

                _panel.Height = 100;
                _previewControlGroupBox.Enabled = false;
                UndoPreviewButton.Enabled = false;
                // PreviewControl.Enabled = false;
            }
            catch (Exception ex)
            {
                GlobalRegistry.UIExceptionNotifier.Notify(ex, "", "Error ");
            }
        }

        private void ApplyChanges_Click(object sender, EventArgs args)
        {
            try
            {
                XmlUILoader uiLoader = new XmlUILoader(new DtdLoader(), new FMDefClassFactory(this.DMClass.Solution));
                UIView uiView = (UIView) uiLoader.LoadUIDef(XMLEditorControl.UIViewXmlEditor.Text);
                XMLEditorControl.CurrentUIView.MarkForDelete();
                if (uiView == null) return;
                this.DMClass.UIViews.Add(uiView);
                SelectorControl.SelectedUIView = uiView;

            }
            catch (Exception ex)
            {
                GlobalRegistry.UIExceptionNotifier.Notify(ex, "", "Error ");
            }
        }

        private void SelectorControl_OnUIViewSelected(object sender, BOEventArgs<UIView> args)
        {
            try
            {
                UIView currentUIView = args.BusinessObject;
                if (currentUIView == null)
                {
                    this.DMClass = null;
                    XMLEditorControl.CurrentUIView = null;
                }
                else
                {
                    this.DMClass = currentUIView.Class;
                    XMLEditorControl.CurrentUIView = currentUIView;
                }
                UpdateState();
            }
            catch (Exception ex)
            {
                GlobalRegistry.UIExceptionNotifier.Notify(ex, "", "Error ");
            }
        }

        private void PreviewGridButton_OnClick(object sender, EventArgs e)
        {
            try
            {
                _previewControlGroupBox.Enabled = true; 
                IUIDef def = XMLEditorControl.CurrentUIDef;
                IUIGrid uiGrid = def.UIGrid;
                if (uiGrid == null) return;
                if (this.DMClass == null) return;
                _panel.Height = 200;
                SolutionValidator solutionValidator = new SolutionValidator((DMSolution) this.DMClass.Solution, _formsController);
                if (solutionValidator.CheckSolutionIsValid())
                {
                    ClassDefCol classDefCol = DMClassToClassDefConverter.Convert((DMSolution) this.DMClass.Solution);
                    IClassDef classDef = classDefCol.FindByClassName("Entity_" + this.DMClass.ClassNameBO);
                    _previewControlGroupBox.Text = string.Format("Preview of {0} grid.", def.Name);
                    PreviewControl.PreviewGrid(classDef, uiGrid);
                }
                UndoPreviewButton.Enabled = true;
            }
            catch (Exception ex)
            {
                GlobalRegistry.UIExceptionNotifier.Notify(ex, "There was a problem parsing the xml:", "Invalid Xml");
            }
        }


        private void PreviewFormButton_OnClick(object sender, EventArgs e)
        {
            try
            {
                _previewControlGroupBox.Enabled = true; 
                IUIDef def = XMLEditorControl.CurrentUIDef;
                IUIForm uiForm = def.UIForm;
                if (uiForm == null) return;
                if (this.DMClass == null) return;
                _panel.Height = 295;
                SolutionValidator solutionValidator = new SolutionValidator((DMSolution) this.DMClass.Solution, _formsController);
                if (solutionValidator.HasWarningsOnly())
                {
                    ClassDefCol classDefCol = DMClassToClassDefConverter.Convert((DMSolution) this.DMClass.Solution);
                    IClassDef classDef = classDefCol.FindByClassName("Entity_" + this.DMClass.ClassNameBO);
                    _previewControlGroupBox.Text = string.Format("Preview of {0} form.", def.Name);
                    PreviewControl.PreviewForm(classDef, def.UIForm);
                }
                UndoPreviewButton.Enabled = true;
            }
            catch (Exception ex)
            {
                GlobalRegistry.UIExceptionNotifier.Notify(ex,
                                                          "There was a problem parsing the xml:", "Invalid Xml");
            }
        }

        private void UpdateState()
        {
            bool enablePreview = this.DMClass != null;
            SelectorControl.Enabled = SelectorControl.UIViews != null;
            XMLEditorControl.Enabled = XMLEditorControl.CurrentUIView != null;
            PreviewControl.Enabled = enablePreview;
            PreviewFormButton.Enabled = enablePreview;
            PreviewGridButton.Enabled = enablePreview;
        }

        public void EditUIViews(BusinessObjectCollection<UIView> uiViews) 
        {
            this.DMClass = null;
            SelectorControl.UIViews = uiViews;
            SelectorControl.SelectedUIView = uiViews != null && uiViews.Count > 0 ? uiViews[0] : null;
            UpdateState();
        }

        
    }
}
